package com.xw.xpermission;

import android.annotation.TargetApi;
import android.content.pm.PackageManager;
import android.os.Build;
import android.os.Bundle;
import android.util.Log;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentActivity;

import java.util.HashMap;
import java.util.Map;

import io.reactivex.rxjava3.subjects.PublishSubject;

public class XPermissionFragment extends Fragment {

    private static final int PERMISSION_REQUEST_CODE = 8888;

    private Map<String, PublishSubject<PermissionX>> mSubjects = new HashMap<>();

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setRetainInstance(true);
    }

    @TargetApi(Build.VERSION_CODES.M)
    void requestPermissions(@NonNull String[] permissions) {
        requestPermissions(permissions, PERMISSION_REQUEST_CODE);
    }

     @TargetApi(Build.VERSION_CODES.M)
    void requestPermissions(@NonNull String[] permissions,String message) {
         CustomXpDialog customXpDialog = new CustomXpDialog(getActivity());
         customXpDialog.setMessage(message);
         customXpDialog.setxPermisReasonListener(new XPermisReasonListener() {
             @Override
             public void onSuccess() {
                 requestPermissions(permissions, PERMISSION_REQUEST_CODE);
             }

             @Override
             public void onRefuse() {
                 for (int i = 0, size = permissions.length; i < size; i++) {
                     Log.d("info","onRequestPermissionsResult  " + permissions[i]);
                     // Find the corresponding subject
                     PublishSubject<PermissionX> subject = mSubjects.get(permissions[i]);
                     if (subject == null) {
                         // No subject found
                         Log.e("info", "RxPermissions.onRequestPermissionsResult invoked but didn't find the corresponding permission request.");
                         return;
                     }
                     mSubjects.remove(permissions[i]);
                     subject.onNext(new PermissionX(permissions[i], false));
                     subject.onComplete();
                 }
             }
         });
         customXpDialog.show();
    }

    @Override
    @TargetApi(Build.VERSION_CODES.M)
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);

        if (requestCode != PERMISSION_REQUEST_CODE) return;

        boolean[] shouldShowRequestPermissionRationale = new boolean[permissions.length];

        for (int i = 0; i < permissions.length; i++) {
            shouldShowRequestPermissionRationale[i] = shouldShowRequestPermissionRationale(permissions[i]);
        }

        onRequestPermissionsResult(permissions, grantResults, shouldShowRequestPermissionRationale);
    }

    void onRequestPermissionsResult(String[] permissions, int[] grantResults, boolean[] shouldShowRequestPermissionRationale) {
        for (int i = 0, size = permissions.length; i < size; i++) {
            Log.d("info","onRequestPermissionsResult  " + permissions[i]);
            // Find the corresponding subject
            PublishSubject<PermissionX> subject = mSubjects.get(permissions[i]);
            if (subject == null) {
                // No subject found
                Log.e("info", "RxPermissions.onRequestPermissionsResult invoked but didn't find the corresponding permission request.");
                return;
            }
            mSubjects.remove(permissions[i]);
            boolean granted = grantResults[i] == PackageManager.PERMISSION_GRANTED;
            subject.onNext(new PermissionX(permissions[i], granted, shouldShowRequestPermissionRationale[i]));
            subject.onComplete();
        }
    }

    @TargetApi(Build.VERSION_CODES.M)
    boolean isGranted(String permission) {
        final FragmentActivity fragmentActivity = getActivity();
        if (fragmentActivity == null) {
            throw new IllegalStateException("This fragment must be attached to an activity.");
        }
        return fragmentActivity.checkSelfPermission(permission) == PackageManager.PERMISSION_GRANTED;
    }

    @TargetApi(Build.VERSION_CODES.M)
    boolean isRevoked(String permission) {
        final FragmentActivity fragmentActivity = getActivity();
        if (fragmentActivity == null) {
            throw new IllegalStateException("This fragment must be attached to an activity.");
        }
        return fragmentActivity.getPackageManager().isPermissionRevokedByPolicy(permission, getActivity().getPackageName());
    }

    public PublishSubject<PermissionX> getSubjectByPermission(@NonNull String permission) {
        return mSubjects.get(permission);
    }

    public void setSubjectForPermission(@NonNull String permission, @NonNull PublishSubject<PermissionX> subject) {
        mSubjects.put(permission, subject);
    }
}
